package tech.bmatch.phone_recognize.service.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import tech.bmatch.phone_recognize.model.PhoneInfo;
import tech.bmatch.phone_recognize.service.PhoneRecognizeService;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 手机号码识别实现
 *
 * @author: Awake
 * @date: 2018-11-10 11:57
 **/
public class PhoneRecognizeServiceImpl implements PhoneRecognizeService {
    /**
     * logger
     */
    private static final Logger logger = LoggerFactory.getLogger(PhoneRecognizeServiceImpl.class);

    /**
     * 手机号码数据内存
     */
    private static Map<String, PhoneInfo> caches = new LinkedHashMap<>();

    /**
     * 初始化读取数据
     */
    static {
        InputStream in = PhoneRecognizeService.class.getResourceAsStream("/phone.data.txt");
        BufferedReader reader = new BufferedReader(
                new InputStreamReader(in)
        );
        reader.lines().forEach(line -> {
            String[] lines = line.split("\t");
            String key = lines[0];
            //赋值
            PhoneInfo phoneInfo = new PhoneInfo();
            caches.put(key, phoneInfo);
            phoneInfo.setProvince(lines[1]);
            phoneInfo.setCity(lines[2]);
            phoneInfo.setOperator(lines[3]);
            phoneInfo.setCityCode(lines[4]);
            phoneInfo.setPostCode(lines[5]);
        });
    }

    /**
     * 根据手机号码查询基本信息
     *
     * @param phone 手机号码
     * @return
     */
    public PhoneInfo onCall(String phone) {
        String phonePrefix = phone.substring(0, 7);
        PhoneInfo phoneInfo;
        //二分法找出匹配的数据
        List<String> list = new ArrayList<>();
        for (Map.Entry<String, PhoneInfo> phoneInfoEntry : caches.entrySet()) {
            list.add(phoneInfoEntry.getKey());
        }
        phoneInfo = binarySearch(list, 0, list.size(), Integer.parseInt(phonePrefix));
        return phoneInfo;
    }

    /**
     * 二分法查找
     *
     * @param arr
     * @param start
     * @param end
     * @param hkey
     * @return PhoneInfo
     */
    public PhoneInfo binarySearch(List<String> arr, int start, int end, int hkey) {
        int result = -1;

        while (start <= end) {
            int mid = start + (end - start) / 2;    //防止溢位
            if (Integer.parseInt(arr.get(mid)) > hkey)
                end = mid - 1;
            else if (Integer.parseInt(arr.get(mid)) < hkey)
                start = mid + 1;
            else {
                result = mid;
                break;
            }
        }
        if (result == -1) {
            return null;
        }
        return caches.get(arr.get(result));
    }
}
